import { PaymentChannel, RechargeStatus } from '@prisma/client';
import { Logger } from '../utils/logger';
import { rechargeService } from './rechargeService';

interface MonitorTask {
  orderId: string;
  channel: PaymentChannel;
  startTime: Date;
  attempts: number;
  maxAttempts: number;
  intervalMs: number;
  timeoutId: NodeJS.Timeout;
}

/**
 * 支付状态监控服务
 * 负责在订单创建后持续监控支付状态，支付成功后自动执行售卡和通知流程
 */
export class PaymentMonitorService {
  private static instance: PaymentMonitorService;
  private monitorTasks: Map<string, MonitorTask> = new Map();

  // 监控配置
  private readonly DEFAULT_INTERVAL_MS = 5000; // 5秒检查一次
  private readonly DEFAULT_MAX_ATTEMPTS = 72; // 6分钟 = 72次 * 5秒 (原来2分钟太短)
  private readonly VARIANCE_MS = 2000; // 随机波动±2秒

  private constructor() {
    Logger.info('PaymentMonitorService 初始化完成');
  }

  public static getInstance(): PaymentMonitorService {
    if (!PaymentMonitorService.instance) {
      PaymentMonitorService.instance = new PaymentMonitorService();
    }
    return PaymentMonitorService.instance;
  }

  /**
   * 开始监控指定订单的支付状态
   */
  public startMonitoring(orderId: string, channel: PaymentChannel): void {
    // 如果已经在监控，先停止旧的监控任务
    if (this.monitorTasks.has(orderId)) {
      Logger.warn(`订单 ${orderId} 已在监控中，停止旧任务并重新开始`);
      this.stopMonitoring(orderId);
    }

    const task: MonitorTask = {
      orderId,
      channel,
      startTime: new Date(),
      attempts: 0,
      maxAttempts: this.DEFAULT_MAX_ATTEMPTS,
      intervalMs: this.DEFAULT_INTERVAL_MS,
      timeoutId: null as any
    };

    this.monitorTasks.set(orderId, task);

    Logger.info(`开始监控订单 ${orderId} 支付状态`, {
      orderId,
      channel,
      intervalMs: task.intervalMs,
      maxAttempts: task.maxAttempts,
      estimatedDuration: `${(task.maxAttempts * task.intervalMs) / 1000}秒`
    });

    // 立即开始第一次检查
    this.scheduleNextCheck(orderId);
  }

  /**
   * 停止监控指定订单
   */
  public stopMonitoring(orderId: string): boolean {
    const task = this.monitorTasks.get(orderId);
    if (!task) {
      return false;
    }

    if (task.timeoutId) {
      clearTimeout(task.timeoutId);
    }

    this.monitorTasks.delete(orderId);

    const duration = Date.now() - task.startTime.getTime();
    Logger.info(`停止监控订单 ${orderId}`, {
      orderId,
      attempts: task.attempts,
      duration: `${duration}ms`,
      reason: '主动停止'
    });

    return true;
  }

  /**
   * 获取当前监控状态
   */
  public getMonitoringStatus(): {
    activeCount: number;
    tasks: Array<{
      orderId: string;
      channel: PaymentChannel;
      attempts: number;
      maxAttempts: number;
      startTime: Date;
      elapsed: number;
    }>;
  } {
    const now = Date.now();
    const tasks = Array.from(this.monitorTasks.values()).map(task => ({
      orderId: task.orderId,
      channel: task.channel,
      attempts: task.attempts,
      maxAttempts: task.maxAttempts,
      startTime: task.startTime,
      elapsed: now - task.startTime.getTime()
    }));

    return {
      activeCount: this.monitorTasks.size,
      tasks
    };
  }

  /**
   * 安排下一次检查
   */
  private scheduleNextCheck(orderId: string): void {
    const task = this.monitorTasks.get(orderId);
    if (!task) {
      return;
    }

    // 添加随机波动 (±2秒)
    const variance = Math.random() * this.VARIANCE_MS * 2 - this.VARIANCE_MS;
    const nextInterval = task.intervalMs + variance;

    task.timeoutId = setTimeout(() => {
      this.performStatusCheck(orderId);
    }, Math.max(1000, nextInterval)); // 最少1秒间隔
  }

  /**
   * 执行支付状态检查
   */
  private async performStatusCheck(orderId: string): Promise<void> {
    const task = this.monitorTasks.get(orderId);
    if (!task) {
      return;
    }

    task.attempts++;
    const elapsed = Date.now() - task.startTime.getTime();
    const progress = ((task.attempts / task.maxAttempts) * 100).toFixed(1);

    Logger.info(`🔍 检查订单 ${orderId} 支付状态`, {
      orderId,
      attempt: task.attempts,
      maxAttempts: task.maxAttempts,
      progress: `${progress}%`,
      elapsed: `${Math.round(elapsed / 1000)}秒`,
      channel: task.channel,
      trigger: 'polling_monitor'
    });

    try {
      // 调用支付状态查询
      const statusResult = await this.queryPaymentStatus(orderId, task.channel);

      if ((statusResult as any).success) {
        const { localRecord, paymentResult } = statusResult as any;

        Logger.info(`✅ 订单 ${orderId} 状态查询成功`, {
          orderId,
          currentStatus: localRecord?.status,
          paymentStatus: paymentResult?.status || 'unknown',
          attempt: task.attempts,
          trigger: 'polling_monitor'
        });

        // 检查是否支付完成
        if (localRecord?.status === RechargeStatus.COMPLETED) {
          Logger.info(`🎉 订单 ${orderId} 支付成功！轮询监控发现支付完成`, {
            orderId,
            attempts: task.attempts,
            duration: `${Math.round(elapsed / 1000)}秒`,
            trigger: 'polling_monitor'
          });

          // 停止监控
          this.stopMonitoring(orderId);

          // 执行售卡和通知流程
          await this.executePostPaymentFlow(orderId);
          return;
        }

        // 检查是否为失败状态
        if (localRecord?.status === RechargeStatus.FAILED ||
            localRecord?.status === RechargeStatus.CANCELLED) {
          Logger.warn(`订单 ${orderId} 支付失败或取消`, {
            orderId,
            status: localRecord.status,
            attempts: task.attempts
          });

          this.stopMonitoring(orderId);
          return;
        }
      } else {
        Logger.warn(`⚠️ 订单 ${orderId} 状态查询失败`, {
          orderId,
          attempt: task.attempts,
          error: (statusResult as any).message || '状态查询失败',
          trigger: 'polling_monitor'
        });
      }

      // 检查是否达到最大尝试次数
      if (task.attempts >= task.maxAttempts) {
        Logger.warn(`⏰ 订单 ${orderId} 监控超时，停止监控`, {
          orderId,
          attempts: task.attempts,
          maxAttempts: task.maxAttempts,
          duration: `${Math.round(elapsed / 1000)}秒`,
          totalDurationMinutes: `${Math.round(elapsed / 60000)}分钟`,
          trigger: 'polling_timeout'
        });

        this.stopMonitoring(orderId);
        return;
      }

      // 继续下一次检查
      this.scheduleNextCheck(orderId);

    } catch (error) {
      Logger.error(`💥 订单 ${orderId} 状态检查异常`, error, {
        orderId,
        attempt: task.attempts,
        maxAttempts: task.maxAttempts,
        channel: task.channel,
        elapsed: `${Math.round(elapsed / 1000)}秒`,
        trigger: 'polling_exception'
      });

      // 异常情况下也继续重试，直到达到最大次数
      if (task.attempts < task.maxAttempts) {
        Logger.info(`🔄 订单 ${orderId} 将继续重试监控`, {
          orderId,
          remainingAttempts: task.maxAttempts - task.attempts,
          trigger: 'polling_retry'
        });
        this.scheduleNextCheck(orderId);
      } else {
        Logger.warn(`❌ 订单 ${orderId} 异常重试次数已达上限，停止监控`, {
          orderId,
          totalAttempts: task.attempts,
          trigger: 'polling_give_up'
        });
        this.stopMonitoring(orderId);
      }
    }
  }

  /**
   * 查询支付状态
   */
  private async queryPaymentStatus(orderId: string, channel: PaymentChannel) {
    try {
      // 调用对应渠道的查询API，这些方法会自动更新本地数据库状态
      const apiResult = await (async () => {
        switch (channel) {
          case PaymentChannel.TOPPAY:
            return await rechargeService.queryTopPayOrderStatus(orderId);
          case PaymentChannel.PAY668:
            return await rechargeService.queryPay668OrderStatus(orderId);
          case PaymentChannel.LSPPAY:
            return await rechargeService.queryLspPayOrderStatus(orderId);
          case PaymentChannel.HUIFENG:
            return await rechargeService.queryHuifengOrderStatus(orderId);
          case PaymentChannel.NASKI:
            return await rechargeService.queryNaskiOrderStatus(orderId);
          default:
            throw new Error(`不支持的支付渠道: ${channel}`);
        }
      })();

      // 重新获取本地记录（查询方法可能已更新状态）
      const localRecord = await rechargeService.getRechargeRecordByOrderId(orderId);

      // 统一返回格式
      return {
        success: true,
        localRecord,
        paymentResult: apiResult,
        message: 'Query successful'
      };
    } catch (error) {
      Logger.error(`查询订单 ${orderId} 支付状态异常`, error);
      return {
        success: false,
        message: error instanceof Error ? error.message : '查询异常'
      };
    }
  }

  /**
   * 执行支付后流程（售卡 + 通知）
   */
  private async executePostPaymentFlow(orderId: string): Promise<void> {
    try {
      Logger.info(`🚀 开始执行订单 ${orderId} 支付后流程`, {
        orderId,
        trigger: 'polling_success'
      });

      // 执行售卡和Telegram通知
      const result = await rechargeService.executeCardSellAndNotify(orderId);

      if (result.success) {
        Logger.info(`✅ 订单 ${orderId} 轮询监控触发的自动发金币完成`, {
          orderId,
          sellCardSuccess: result.sellCardSuccess,
          telegramSent: result.telegramSent,
          message: result.message,
          trigger: 'polling_success'
        });
      } else {
        Logger.error(`❌ 订单 ${orderId} 轮询监控触发的自动发金币失败`, {
          orderId,
          message: result.message,
          trigger: 'polling_failure'
        });
      }
    } catch (error) {
      Logger.error(`💥 订单 ${orderId} 支付后流程异常`, error, {
        orderId,
        trigger: 'polling_exception'
      });
    }
  }

  /**
   * 清理所有监控任务（用于服务关闭时）
   */
  public cleanup(): void {
    Logger.info(`🧹 清理所有监控任务，当前活跃任务数: ${this.monitorTasks.size}`);

    for (const [_orderId, task] of this.monitorTasks) {
      if (task.timeoutId) {
        clearTimeout(task.timeoutId);
      }
    }

    this.monitorTasks.clear();
    Logger.info('✅ 所有监控任务已清理完成');
  }
}

// 导出单例实例
export const paymentMonitorService = PaymentMonitorService.getInstance();